#include "scene.h"

#include "IndexBuffer.h"
#include "Material.h"
#include "Texture2D.h"
#include "UniformBuffer.h"
#include "VertexBuffer.h"

#include "FSQ.h"
#include "FrameBuffer.h"
#include "Ground.h"
#include "Model.h"
#include "XVulkan.h"

Texture2D *texture = nullptr;

Material *fsq_material = nullptr;
XFixedPipeline *fsq_pipeline = nullptr;

FSQ *fsq = nullptr;

void Init()
{
    glm::vec3 camera_pos(0.0f, 5.0f, 15.0f);
    glm::vec3 light_pos(0.0f, 5.0f, 0.0f);
    glm::mat4 projection = glm::perspective(45.0f, float(xGetViewportWidth()) / float(xGetViewportHeight()), 0.1f, 100.0f);
    projection[1][1] *= -1.0f;

    glm::mat4 light_view = glm::lookAt(light_pos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f));

    texture = new Texture2D();
    texture->SetImage("Res/test.bmp");

    // ===============fsq
    fsq_material = new Material();
    fsq_material->Init("Res/fsq.vsb", "Res/fsq.fsb");
    fsq_material->mFragVec4UBO->SetVector4(0, light_pos.x, light_pos.y, light_pos.z, 1.0f);
    fsq_material->mFragVec4UBO->SetVector4(1, 10.0f, 10.0f, 10.0f, 1.0f);
    fsq_material->mFragVec4UBO->SetVector4(2, camera_pos.x, camera_pos.y, camera_pos.z, 1.0f);
    fsq_material->mFragMat4UBO->SetMatrix(0, projection);
    fsq_material->mFragMat4UBO->SetMatrix(1, light_view);
    fsq_material->SubmitUniformBuffers();

    fsq_pipeline = new XFixedPipeline();
    xSetColorAttachmentCount(fsq_pipeline, 1);

    fsq_pipeline->mRenderPass = xGetGlobalRenderPass();
    fsq_pipeline->mViewport = {0.0f, 0.0f, float(xGetViewportWidth()), float(xGetViewportHeight()), 0.0f, 1.0f};
    fsq_pipeline->mScissor = {{0, 0}, {uint32_t(xGetViewportWidth()), uint32_t(xGetViewportHeight())}};
    fsq_pipeline->mInputAssetmlyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;

    fsq_material->SetFixedPipeline(fsq_pipeline);
    fsq_material->SetTexture(0, texture);
    fsq_material->Finish();

    fsq = new FSQ();
    fsq->Init();
    fsq->mMaterial = fsq_material;
}

void Draw(float deltaTime)
{
    VkCommandBuffer commandbuffer = xBeginRendering();
    fsq->Draw(commandbuffer);
    xEndRendering();
    xSwapBuffers();
}

void OnViewportChanged(int width, int height)
{
    xViewport(width, height);
    fsq_pipeline->mViewport = {0.0f, 0.0f, float(xGetViewportWidth()), float(xGetViewportHeight()), 0.0f, 1.0f};
    fsq_pipeline->mScissor = {{0, 0}, {uint32_t(xGetViewportWidth()), uint32_t(xGetViewportHeight())}};
}

void OnQuit()
{
    delete texture;

    delete fsq;
    delete fsq_material;
    delete fsq_pipeline;

    xVulkanCleanUp();
}